#include "EXmlNode.h"
#include "DefineCommon.h"
#include "EString.h"
#include "EVariant.h"
#include <EItemVisitor.h>
#include <Autogen/EXmlNode_autogen.h>

class EItemVisitorStatistics;
typedef SmartPtr(EItemVisitorStatistics) EItemVisitorStatisticsPtr;
class EItemVisitorStatistics : public EItemVisitor
{
public:
    EItemVisitorStatistics()
    {
    }

    virtual ~EItemVisitorStatistics()
    {
    }
    
    /*overwrite EItemVisitor's core function*/
    virtual bool handleEItem(EItemPtr item, int depth, EItemPtr parentItem)
    {
        EString itemName = item->getName();
        if(itemName.contains(this->m_targetTypeName))
        {
            this->m_count++;
        }
        return true;
    }
    
    EString m_targetTypeName;
    int m_count = 0;
protected:
};

class EItemVisitorStatisticsAll;
typedef SmartPtr(EItemVisitorStatisticsAll) EItemVisitorStatisticsAllPtr;
class EItemVisitorStatisticsAll : public EItemVisitor
{
public:
    EItemVisitorStatisticsAll()
    {
    }

    virtual ~EItemVisitorStatisticsAll()
    {
    }
    
    /*overwrite EItemVisitor's core function*/
    virtual bool handleEItem(EItemPtr item, int depth, EItemPtr parentItem)
    {
        EItemMetaPropertyPtr prop = item->getOrCreatMeta()->getProperty("type");
        if(prop == nullptr)
        {
            return true;
        }

        EString typeStr = prop->value.to_EString();
        if(typeStr.isEmpty())
        {
            return true;
        }

        
        if(m_mapTypeCount.count(typeStr) == 0)
        {
            m_mapTypeCount[typeStr] = 1;
        }
        else
        {
            m_mapTypeCount[typeStr] = m_mapTypeCount[typeStr]+1;
        }

        return true;
    }
    
    EString m_targetTypeName;
    EMap<EString, int> m_mapTypeCount;
    int m_count = 0;

protected:
};

EXmlNode::EXmlNode()
{
    EXmlNode_construct_autogen(this);
}

EXmlNode::~EXmlNode()
{
}
    
void EXmlNode::ui_DirectChildCount()
{
    ELOG_INFO("DirectChildCount=%d", this->getChildCount());
}

void EXmlNode::OnSet_ui_NameForStatistics(const EString& value)
{
    this->ui_NameForStatistics = value;
}

void EXmlNode::ui_StatisticsByTypeName()
{
    EItemVisitorStatisticsPtr visitor = NewSmartPtr(EItemVisitorStatistics)();
    visitor->m_targetTypeName = this->ui_NameForStatistics;
    visitor->travelEItem(shared_from_this());

    ELOG_INFO("Count of %s is %d", this->ui_NameForStatistics.data(), visitor->m_count);
}

void EXmlNode::ui_StatisticsAll()
{
    EItemVisitorStatisticsAllPtr visitor = NewSmartPtr(EItemVisitorStatisticsAll)();
    visitor->travelEItem(shared_from_this());

    EMap<EString, int>::iterator it;
    EString infoStr;
    for(it = visitor->m_mapTypeCount.begin(); it != visitor->m_mapTypeCount.end(); it++)
    {
        infoStr += it->first;
        infoStr += ": ";
        infoStr += EString::number(it->second);
        infoStr += "\n";
    }

    ELOG_INFO("The result of statistics all:\n%s", infoStr.data());

}
